/**
* @file
* Custom locale information header file.
*
* Copyright (c) 2009 by Pete Black <theblackpeter@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA  02111-1307, USA.
*
* @author Pete Black <theblackpeter@gmail.com>
*/
#ifndef KISALOCALE_H
#define KISALOCALE_H

#include <QLocale>
#include <QMap>

/**
 * @class KisaLocale
 *
 * The KisaLocale class adds missing locale support that is currently not
 * provided by QLocale. The main missing feature is a convenient way to go from
 * two-letter ISO 3166 country code to a two-letter ISO 639 language code. That
 * is, if the country is given by "us" then using the map in KisaLocale one can
 * get the main language "en" and with these construct a locale on the form of:
 * @c language_COUNTRY, that is @c "en_US".
 *
 * The country-language pairs map are generated using Qt's own locale system and
 * no guarantees are made about it's completeness or correctness.
 *
 * This has now been extended to include support for keyboard layout to
 * language mappings, which is what one would most likely need.
 *
 * Copyright (c) 2009 by Pete Black <theblackpeter@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * @author Pete Black <theblackpeter@gmail.com>
 */
class KisaLocale {

  public:

  /**
   * Default constructor. Will fill both the @c countryToLanguageMap and
   * @c keyboardLayoutToLanguageMap if not done.
   */
  KisaLocale();

  /**
   * Destructor.
   */
  virtual ~KisaLocale();

  /**
   * Dose a lookup in the countryToLanguageMap to get the language associated
   * with the given country defined by @p countryCode.
   *
   * @param countryCode the two-letter ISO 3166 country code to get the language
   * for
   * @return the two-letter ISO 639 language code of the most common language
   * for the given country code or an empty string if none is found
   */
  const QString getLanguageFromCountryCode(const QString& countryCode);

  /**
   * Does a lookup in the keyboardLayoutToLanguageMap to get the locale language
   * associated with the given keyboard layout @p keyboardLayout.
   *
   * The locale language is the full four-letter ISO code, @c language_COUNTRY
   * (ISO 639 and ISO 3166).
   *
   * @param keyboardLayout the keyboard layout to get the locale for
   *
   * @return a QLocale object based on the language
   */
  const QLocale getLocaleFromKeyboardLayout(const QString& keyboardLayout);

  /**
   * Creates a locale object based on the given two-letter ISO 639 language
   * code. If the language code is valid the QLocale return will be non-default
   * one. Use this function to test if a string is a valid language code.
   *
   * @param languageCode language code to generate the locale from
   * @return the locale object based on the given language code, or the default
   * locale "C" if no match was found
   *
   * @see guessLocale()
   */
  const QLocale guessLocaleFromLanguageCode(const QString& languageCode);

  /**
   * Creates a locale object based on the given country by using the most common
   * language for that country.
   *
   * The use of the term guess here implies that this is not always accurate, so
   * use with care.
   *
   * @note This is something that QLocale is not capable of doing.
   *
   * @param countryCode the two-letter ISO 3166 country code to get the locale
   * for
   * @return a locale based on the country or a default locale if no language
   * match is found
   *
   * @see guessLanguage()
   */
  const QLocale guessLocaleFromCountryCode(const QString& countryCode);

  private:

  /**
   * Loads the the given map with default country-language pairs based on
   * Qt's locale data. This is done by iterating over the QLocale::Languages
   * enum and grabbing their corresponding country. The map is generated on a
   * first seen bases. As most of the language in the QLocale::Languages enum
   * are in alphabetical order, the stored country-language pair will usually
   * contain the first language in alphabetical order for that country.
   *
   * For example: In the QLocale database Canada has the languages English and
   * French associated with it, but here we'll only store English as it will be
   * first seen.
   *
   * @note all country-language pairs are stored in their two-letter ISO 3166
   * and ISO 639 codes.
   */
  static void loadDefaultCountryToLanguageMap();

  /**
   * Loads the mappings defined in mappings_override.txt which are used to add
   * and override the default values in @c countryToLanguageMap and
   * @c keyboardLayoutToLanguageMap.
   *
   * @note all country-language pairs in @c countryToLanguageMap are stored in
   * their respective two-letter ISO 3166 and ISO 639 codes and the language
   * locale in keyboardLayoutToLanguageMap is in the full four-letter ISO code
   *
   * @note this will change mapToUpdate directly
   */
  static void updateOverrideMaps();

  /**
   * Dictionary containing two-letter ISO 3166 country code to two-letter
   * ISO 639 language code mappings.
   *
   * Example:
   * @code
   *    countryToLanguageMap["us"] -> "en"
   * @endcode
   */
  static QMap<QString, QString> countryToLanguageMap;

  /**
   * Dictionary map containing keyboard layout to language mappings.
   * The keyboard layout can be on pretty much any form and the language is in
   * the full four-letter code ISO code country_LANGUAGE (ISO 3166 and ISO 639).
   */
  static QMap<QString, QString> keyboardLayoutToLanguageMap;
};
#endif
